package com.yunduo.config.shiro.realm;

import com.yunduo.common.YunDuoUtils;
import com.yunduo.config.shiro.ShiroConfig;
import com.yunduo.entity.Role;
import com.yunduo.entity.User;
import com.yunduo.service.RoleService;
import com.yunduo.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * 自定义授权与认证类
 */
@Component
public class YunDuoAuthRealm extends AuthorizingRealm {

    //用户服务
    @Resource
    private UserService userService;
    //角色服务
    @Resource
    private RoleService roleService;
    @Resource
    private ShiroConfig config;

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        User user = userService.getUserByName(principalCollection.getPrimaryPrincipal().toString());
        String[] roleIds = user.getRole().split("_");
        List<Role> roles = roleService.getRolesByIds(Arrays.asList(roleIds));
        if(null == roles){
            return null;
        }
        //添加权限
        roles.forEach(role -> simpleAuthorizationInfo.addRole(role.getRole()));
        return simpleAuthorizationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获取登录用户信息
        String name = authenticationToken.getPrincipal().toString();
        //查询数据库获得信息
        User userLogin = userService.getUserByName(name);
        //获取用户对象
        if(null != userLogin){
            //封装认证对象
            SimpleAuthenticationInfo loginInfo = new SimpleAuthenticationInfo(
                    userLogin.getName(), //登录用户名对象
                    userLogin.getPassword(), //登录用户的密码 <- 数据库
                    ByteSource.Util.bytes(config.salt), // 盐 <-加密手段
                    name //登录用户名字符串
            );
            //返回认证对象
            return loginInfo;
        }
        return null;
    }
}
